home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dutil / bintohex.c next >
C/C++ Source or Header  |  1997-09-09  |  6KB  |  267 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6. /*
  7.  *  $Id: bintohex.c,v 30.326 1995/12/24 06:12:59 dice Exp dice $
  8.  *
  9.  *  bintohex infile [outfile]
  10.  *
  11.  *  (Was) compilable on an IBM-PC or Amiga  _fmode is for Lattice C on the IBM,
  12.  *  is IGNORED by Aztec C on the Amiga.  Note that INT and CHAR are not
  13.  *  used as ibm's lattice C uses 16 bit ints and unsigned chars.  Change
  14.  *  as needed.    No guarentees for the IBMPC version.
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20.  
  21. #include <lib/version.h>
  22.  
  23. IDENT("bintohex",".2");
  24. DCOPYRIGHT;
  25.  
  26. #ifdef IBM
  27. typedef char ubyte;
  28. typedef unsigned uword;
  29. typedef int void;
  30. #else
  31. typedef unsigned char ubyte;
  32. typedef unsigned short uword;
  33. #endif
  34.  
  35. #define PERLINE 16
  36.  
  37. void exiterr (ubyte *);
  38. void convert (int, FILE *, FILE *, unsigned long);
  39. uword getwlh (FILE *);
  40. ubyte puth (ubyte, FILE *);
  41.  
  42. uword _fmode = 0;
  43.  
  44. int
  45. main(int ac, char **av)
  46. {
  47.     char format=1;    /* 'i'=Intel.  1,2,3 = Motorola S1-S3 formats. */
  48.     FILE *infile;
  49.     FILE *outfile;
  50.     char *inName=0;
  51.     char *outName=0;
  52.     int  i;
  53.     unsigned long   org=0;    /* Hex file origin */
  54.  
  55.     _fmode = 0x8000;
  56.     if (ac == 1 || ( ac == 2  &&  *av[1]=='?' ) ) {
  57.         puts(Ident);
  58.         puts(DCopyright);
  59.     puts("bintohex <infile> -o [outfile] -s[1,2,3] [-i] [-O offset]");
  60.     puts("; Convert <infile> to Motorola or Intel Hex format");
  61.     exit(5);
  62.     }
  63.  
  64.     for (i = 1; i < ac; ++i) {
  65.     char *ptr = av[i];
  66.     char *dummy;
  67.  
  68.     if (*ptr != '-') {
  69.         inName = ptr;
  70.         continue;
  71.     }
  72.     ptr += 2;
  73.     switch(ptr[-1]) {
  74.     case 'o':
  75.         if (*ptr == 0)        /* Space is optional */
  76.         ptr = av[++i];
  77.  
  78.         outName = ptr;
  79.         break;
  80.     case 'i':
  81.     case 'I':
  82.         format='i';
  83.         break;
  84.     case 's':
  85.     case 'S':
  86.         format=*ptr-'0';
  87.         if (format<1 || format >3) {
  88.         printf("Format %s not supported.  Use  S1, S2 or S3.\n",av[i]);
  89.         exit(10);
  90.         }
  91.         break;
  92.     case 'O':
  93.         if (*ptr == 0)
  94.         ptr = av[++i];
  95.         org = strtol(ptr, &dummy, 0);
  96.         break;
  97.     default:
  98.         printf("Bad option: %s\n", av[i]);
  99.         exit(10);
  100.     }
  101.     }
  102.  
  103.     if(!inName) {
  104.     printf("No input file specified\n");
  105.     exit(10);
  106.     }
  107.     infile = fopen(inName, "r");
  108.     if (infile == NULL) {
  109.     printf("Unable to open input file %s\n",inName);
  110.     exit(10);
  111.     }
  112.     outfile = (outName) ? fopen(outName, "w") : stdout;
  113.     if (outfile == NULL) {
  114.     printf("Unable to open output file %s\n",outName);
  115.     exit(10);
  116.     }
  117.     convert(format, infile, outfile, org);
  118.     putc('z'&0x1F, outfile);    /* ^Z as end of file marker (for BP programmer) */
  119.     fclose(infile);
  120.     fclose(outfile);
  121.     return(0);
  122. }
  123.  
  124.  
  125. /*
  126.  *  Intel Hex output (MCS80 format):
  127.  *
  128.  *  :lloooott(ll bytes hex code)cc  ll=# of bytes
  129.  *                    oooo=origin (high/low format)
  130.  *                    tt="record type"
  131.  *                    (00=norm,01=end,02=extended,03=code start)
  132.  *                    cc=invert of checksum all codes
  133.  *                    <cr/lf> after each line
  134.  *
  135.  *  Extended Intel Hex (MCS-86 format).  Adds segment:    20 bits, 1 Megabyte:
  136.  *        :ll0000ffaaaass     ll-# of bytes (set to 02)
  137.  *                    ff-format type (set to 02)
  138.  *                    aaaa-segment offset (address/16)
  139.  *                    ss-checksum
  140.  *
  141.  *
  142.  *  Motorola Hex files:
  143.  *        Sxnn[[[aaaa]aa]aa]dd..ddss
  144.  *            x    =Type 1=4 byte address, 64KB limit
  145.  *                 Type 2=6 byte address, 16MB limit
  146.  *                 Type 3=8 byte address, 4 GB limit
  147.  *            nn    =Number of bytes+3
  148.  *            aaaa    =address
  149.  *            dd..dd    =Data
  150.  *            ss    =Checksum
  151.  *
  152.  */
  153. void
  154. convert(format, in, out, org)
  155. int  format;
  156. FILE *in;
  157. FILE *out;
  158. unsigned long    org;
  159. {
  160. uword        idx;
  161. unsigned long    len;
  162. ubyte        buf[256];
  163.  
  164.   fseek(in, 0L, 2);          /* Seek to end of file */
  165.   len = ftell(in);
  166.   fseek(in, 0, 0);
  167.  
  168.   if(format == 'i') {
  169.     /************************ Intel **********************************/
  170.     for (;;) {
  171.     while (len > 0) {
  172.         register ubyte chk;
  173.         register short i;
  174.  
  175.         idx = (len > PERLINE) ? PERLINE : len;
  176.         fread(buf, idx, 1, in);
  177.         putc(':', out);
  178.         puth((ubyte)idx, out);
  179.         puth((ubyte)(org >> 8), out);
  180.         puth((ubyte)(org & 0xFF), out);
  181.         putc('0', out);
  182.         putc('0', out);
  183.         chk = idx + (org >> 8) + (org & 0xFF);
  184.         for (i = 0; (uword)i < idx; ++i) {
  185.         chk += buf[i];
  186.         puth(buf[i], out);
  187.         }
  188.         puth((ubyte)-chk, out);
  189.         putc('\r', out);
  190.         putc('\n', out);
  191.         len -= idx;
  192.         org += idx;
  193.     }
  194.     break;
  195.     }
  196.     fprintf(out, ":00000001FF\r\n");
  197.     /* End Intel */
  198.     } else {
  199.     /*********************** Motorola ********************************/
  200.  
  201.     /*
  202.     if(format==1)
  203.     if(len > 0xFFFF)
  204.         printf("Warning: file size greater than 64K S1 limit. Use S2\n");
  205.     if(format==2)
  206.     if(len > 0xFFFFFF)
  207.         printf("Warning: file size greater than 16Mb S2 limit. Use S3\n");
  208.     */
  209.  
  210.     for (;;) {
  211.     while (len > 0) {
  212.         register ubyte chk;
  213.         register short i;
  214.  
  215.         idx = (len > PERLINE) ? PERLINE : len;
  216.         fread(buf, idx, 1, in);
  217.  
  218.         putc('S', out);
  219.         putc(format+'0',out);
  220.  
  221.         puth((ubyte)idx+2+format, out);
  222.  
  223.         chk=idx+2+format;
  224.         if(format==3) {
  225.             chk += puth((ubyte)(org >>24), out);
  226.             chk += puth((ubyte)(org >>16), out);
  227.             }
  228.         if(format==2) {
  229.             chk += puth((ubyte)(org >>16), out);
  230.             }
  231.         chk += puth((ubyte)(org >> 8), out);
  232.         chk += puth((ubyte)(org & 0xFF), out);
  233.  
  234.         for (i = 0; (uword)i < idx; ++i) {
  235.         chk += puth(buf[i], out);
  236.         }
  237.         puth((ubyte)0xff-chk, out);
  238.         putc('\r', out);
  239.         putc('\n', out);
  240.         len -= idx;
  241.         org += idx;
  242.     }
  243.     break;
  244.     }
  245.     fprintf(out, "S%c\r\n",10-format+'0');     /* S9,S8,S7 */
  246.   } /* End Motorola */
  247. }
  248.  
  249. uword
  250. getwlh(in)
  251. FILE *in;
  252. {
  253.     uword result;
  254.  
  255.     result = getc(in);
  256.     result += getc(in) << 8;
  257.     return(result);
  258. }
  259.  
  260. ubyte puth(ubyte c, FILE *out)
  261. {
  262.     static ubyte dig[] = { "0123456789ABCDEF" };
  263.     putc(dig[(c>>4)&15], out);
  264.     putc(dig[c&15], out);
  265.     return(c);
  266. }
  267.